package com.mxx.basic.server;

import com.mxx.basic.server.enums.RequestEnum;
import com.mxx.basic.server.http.OkHttpManager;
import com.mxx.basic.server.retrofit.manager.ApiServiceManager;
import com.mxx.basic.server.retrofit.request.ApiService;

import com.mxx.basic.utils.Logger;

import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitHelper {
    String mBaseUrl;
    String mUrl;
    Map<String, String> mHeaders;
    Map<String, String> mParamsStrMap;
    Object mObjParams;
    String mJsonString;
    String mFileName;
    List<String> mFilePaths;
    Map<String, Object> mParamsObjMap;
    Observable<Response<ResponseBody>> observable;
    /**
     * 日志打印类
     */
    Logger mLogger;
    String msg;
    boolean isShowLoading;

    private RetrofitHelper(Builder builder) {
        this.mBaseUrl = builder.mBaseUrl;
        this.mUrl = builder.mUrl;
        this.mHeaders = builder.mHeaders;
        this.mParamsStrMap = builder.mParamsStrMap;
        this.mObjParams = builder.mObjParams;
        this.mJsonString = builder.mJsonString;
        this.mFileName = builder.mFileName;
        this.mFilePaths = builder.mFilePaths;
        this.mParamsObjMap = builder.mParamsObjMap;
        mLogger = Logger.getInstance();
        msg = "";
    }


    public Observable<Response<ResponseBody>> observable(RequestEnum requestEnum) {
        ApiService apiService = createService();
        if (apiService == null) {
            return null;
        }
        switch (requestEnum) {
            case METHOD_GET_NO_PARAMS:
                observable = apiService.executeMethodGet(mUrl);
                break;
            case METHOD_POST_JSON_STRING:
                RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json;charset=UTF-8"), mJsonString);
                observable = apiService.executePostJsonMethod(mUrl, body);
                break;
            case METHOD_POST_FORM:
                observable = apiService.executePostFormMethod(mUrl, mParamsStrMap);
                break;
            case METHOD_DOWNLOAD:
                observable = apiService.executeDownload(mUrl);
                break;
        }
        if (observable == null) {
            return null;
        }
        return observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    private ApiService createService() {
        Retrofit retrofit = null;
        try {
            OkHttpClient.Builder builder = new OkHttpManager().getOkHttpBuilder();
            //获取OkHttpClient
            OkHttpClient client = builder
                    .build();
            retrofit = new Retrofit.Builder()
                    .baseUrl(mBaseUrl)
                    .client(client)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (retrofit == null) {
            return null;
        }
        return ApiServiceManager.create(retrofit);
    }

    public static final class Builder {
        String mBaseUrl;
        String mUrl;
        Map<String, String> mHeaders;
        Map<String, String> mParamsStrMap;
        Object mObjParams;
        String mJsonString;
        String mFileName;
        List<String> mFilePaths;
        Map<String, Object> mParamsObjMap;
        boolean showLoading;

        public Builder() {

        }

        public Builder(RetrofitHelper helper) {
            this.mBaseUrl = helper.mBaseUrl;
            this.mUrl = helper.mUrl;
            this.mHeaders = helper.mHeaders;
            this.mParamsStrMap = helper.mParamsStrMap;
            this.mObjParams = helper.mObjParams;
            this.mJsonString = helper.mJsonString;
            this.mFileName = helper.mFileName;
            this.mFilePaths = helper.mFilePaths;
            this.mParamsObjMap = helper.mParamsObjMap;
            this.showLoading = helper.isShowLoading;
        }

        public Builder baseUrl(String mBaseUrl) {
            this.mBaseUrl = mBaseUrl;
            return this;
        }

        public Builder appendUrl(String url) {
            this.mUrl = url;
            return this;
        }

        public Builder addHeaders(Map<String, String> headers) {
            this.mHeaders = headers;
            return this;
        }

        public Builder addParams(Map<String, String> params) {
            this.mParamsStrMap = params;
            return this;
        }

        public Builder addParams(Object objectParams) {
            this.mObjParams = objectParams;
            return this;
        }

        public Builder addParams(String jsonString) {
            this.mJsonString = jsonString;
            return this;
        }

        public Builder addParams(List<String> filePaths) {
            this.mFilePaths = filePaths;
            return this;
        }

        public Builder setFileName(String fileName) {
            this.mFileName = fileName;
            return this;
        }

        public Builder isShowLoading(boolean showLoading) {
            this.showLoading = showLoading;
            return this;
        }

        public RetrofitHelper build() {
            return new RetrofitHelper(this);
        }

    }
}
